﻿// This program is a modification of the C++ Base64_RC4.h into a C# program
//Base64_RC4.h : implementation of the Base64 and RC4 algorithm class
//
/*
 * Base64_RC4.h  - Copyright (C) 2006 Jerry Jiang
 *
 * Email  :jerryJBL@gmail.com
 * 
 * RC4.cs written by Chris Tisdale
 *
 */

using System;
using System.Collections.Generic;
using System.Text;

namespace Common_Code.Encryptions
{
    public class RC4 : Encryption
    {
        /*
         * These are the private variables used throught the function
         */
        private byte[] pszKey;
        private byte[] pszText;
        private byte[] sbox;
        private byte[] key;
        private byte k;
        private int m, n, i, j, ilen;

        /*
         * Name: RC4
         * 
         * Parameters: byte[] pszText
         *             byte[] pszKey
         * 
         * Returns: An RC4 Object
         * 
         * Purpose: Creates a RC4 encryption object
         */
        public RC4(byte[] pszText, byte[] pszKey)
        {
            this.sbox = new byte[256];
            this.key = new byte[256];
            this.pszText = pszText;
            this.pszKey = pszKey;
        }

        /*
         * Name: ~RC4
         * 
         * Parameters: None
         * 
         * Returns: None
         * 
         * Purpose: Clears the information in memory
         */
        ~RC4()
        {
            Array.Clear(sbox, 0, sbox.Length);
            Array.Clear(sbox, 0, key.Length);
            Array.Clear(pszText, 0, pszText.Length);
            Array.Clear(pszKey, 0, pszKey.Length);
        }

        /*
         * Name: Encrypt
         * 
         * Parameters: NA
         * 
         * Returns: byte[]
         * 
         * Purpose: This function is used to Encrypt text
         */
        public byte[] Encrypt()
        {
            i = 0;
            j = 0;
            n = 0;
            ilen = pszText.Length;
            for (m = 0; m < 256; m++)
            {
                key[m] = pszKey[m % ilen];
                sbox[m] = (byte)m;
            }

            for (m = 0; m < 256; m++)
            {
                n = (n + sbox[m] + key[m]) & 0xFF;
                Common_Code.Heler_Functions.HelperClass.Swap<byte>(ref sbox[m], ref sbox[n]);
            }

            ilen = pszText.Length;
            for (m = 0; m < ilen; m++)
            {
                i = (i + 1) & 0xff;
                j = (j + sbox[i]) & 0xff;
                Common_Code.Heler_Functions.HelperClass.Swap<byte>(ref sbox[i], ref sbox[j]);
                k = (sbox[((sbox[i] + sbox[j]) & 0xff)]);
                if (k == pszText[m])
                    k = 0;
                pszText[m] ^= k;
            }
            return pszText;
        }

        /*
         * Name: Decrypt
         * 
         * Parameters: NA
         * 
         * Returns: byte[]
         * 
         * Purpose: This function is used to Decrypt text that is already Encrypted
         */
        public byte[] Decrypt()
        {
            return Encrypt();
        }

        /*
         * Name: SetKey
         * 
         * Parameters: byte[] pszKey
         * 
         * Returns: None
         * 
         * Purpose: This function sets the key for the encryption algorithm
         */
        public void SetKey(byte[] pszKey)
        {
            this.pszKey = pszKey;
        }

        /*
         * Name: SetText
         * 
         * Parameters: byte[] pszText
         * 
         * Returns: None
         * 
         * Purpose: This function sets the text for the encryption algorithm
         */
        public void SetText(byte[] pszText)
        {
            this.pszText = pszText;
        }
    }
}
